package com.atguigu.gmall.mq.receiver;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.mq.config.DeadLetterMqConfig;
import com.atguigu.gmall.mq.config.DelayedMqConfig;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Author atguigu-mqx
 * @Description TODO
 * @Date 2023/7/25 9:36
 * @Version 1.0
 */
@Component
public class ConfirmReceiver {

    @Autowired
    private RedisTemplate redisTemplate;


    //  监听消息需要使用注解来完成
    //  1.  第一个功能就是帮助我们初始化绑定关系. 2. 还能监听当前这个队列中的消息.
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "queue.confirm",durable = "true",autoDelete = "false"),
            exchange = @Exchange(value = "exchange.confirm"),
            key = {"routing.confirm"}
    ))
    public void getMsg(String msg , Channel channel, Message message){
        try {
            //  获取到消息
            System.out.println("消息："+msg);
            System.out.println("消息："+new String(message.getBody()));
            //  如果有消费失败的时候，那么你是如何处理的?
            //  int i = 1/0;
            //  出现了网络异常 ，重试消费.
        } catch (Exception e) {
            //  重试消费. 重回队列. 能否借助 redis 来记录当前消费的次数。超过5，则记录到消息记录表.
            /*
                if(count>=5){
                    channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
                }else{
                    channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
                }
             */
            //  insert into msg(); 后续人工处理.
            e.printStackTrace();
        }
        //  第一个参数：表示消息唯一标识；第二个参数：表示是否批量确认 一定不会产生消息积压.
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

    //  监听消息
    @SneakyThrows
    @RabbitListener(queues = DeadLetterMqConfig.queue_dead_2)
    public void getMsg1(String msg , Channel channel, Message message){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //  获取到消息
        System.out.println("消息："+msg);
        System.out.println(simpleDateFormat.format(new Date()));
        //  第一个参数：表示消息唯一标识；第二个参数：表示是否批量确认
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

    //  监听消息
    @SneakyThrows
    @RabbitListener(queues = DelayedMqConfig.queue_delay_1)
    public void getMsg2(JSONObject jsonObject , Channel channel, Message message){
        //  setnx key value; key=必须唯一不能重复.
        String id = message.getMessageProperties().getHeader("spring_returned_message_correlation");
        System.out.println("msg:\t"+id);
        //  获取消息Id
        String messageId = (String) jsonObject.get("messageId");
        Boolean result = this.redisTemplate.opsForValue().setIfAbsent(messageId, messageId);
        //  判断
        if (result){
            try {
                //  执行成功.
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                //  获取到消息
                System.out.println("消息："+jsonObject.get("message"));
                System.out.println(simpleDateFormat.format(new Date()));
//                int i=1/0;
                //  第一个参数：表示消息唯一标识；第二个参数：表示是否批量确认
            } catch (Exception e) {
                this.redisTemplate.delete(messageId);
                throw new RuntimeException(e);
            }finally {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            }
        }else {
            //  确认了,消息处理，出队.
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            //  消除没有正确处理， 出队.
            //  channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
        }
        //  正确处理，没有正确处理！


    }
}
